import java.util.concurrent.Executor;
import jdk.internal.vm.Continuation;
import jdk.internal.vm.ContinuationScope;
import sun.misc.Unsafe;

// java --enable-preview --add-opens java.base/jdk.internal.vm=ALL-UNNAMED Loom2
public class Loom2 {
	public static void main(String[] args) throws Exception {
		var f = Unsafe.class.getDeclaredField("theUnsafe");
		f.setAccessible(true);
		var U = (Unsafe)f.get(null);
		long OVERRIDE_OFFSET;
		for (long i = 0; ; ) {
			if (U.getBoolean(f, i)) {
				f.setAccessible(false);
				if (!U.getBoolean(f, i)) {
					OVERRIDE_OFFSET = i;
					break;
				}
				f.setAccessible(true);
			}
			if (++i == 32) // should be enough
				throw new UnsupportedOperationException();
		}
		var tb = Thread.ofVirtual();
		f = tb.getClass().getDeclaredField("scheduler");
		U.putBoolean(f, OVERRIDE_OFFSET, true); // f.setAccessible(true);
		f.set(tb, (Executor)Runnable::run);

		var cs = new ContinuationScope("VirtualThreads");
		var c = new Continuation(cs, () -> {
			System.out.println("in Continuation: begin " + Thread.currentThread());
			Continuation.yield(cs);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
			System.out.println("in Continuation: end " + Thread.currentThread());
		});
		System.out.println("main: begin " + Thread.currentThread());
		c.run();
		System.out.println("main: continue " + Thread.currentThread());
		c.run();
		System.out.println("main: end " + Thread.currentThread());
	}
}
